﻿using System;
using System.Linq;
using JetBrains.Annotations;
using JetBrains.ReSharper.Psi.Xaml.Impl;
using JetBrains.ReSharper.Psi.Xaml.Parsing;
using JetBrains.ReSharper.Psi.Xaml.Tree;
using JetBrains.ReSharper.Psi.Xaml.Tree.MarkupExtensions;
using JetBrains.ReSharper.Psi.Xml.Tree;
using JetBrains.Text;
using JetBrains.Util;

namespace GammaJul.ReSharper.GammaXaml.Psi.Xaml {

	/// <summary>
	/// Contains extension methods related to <see cref="XamlElementFactory"/>.
	/// </summary>
	public static class XamlElementFactoryExtensions {

		/// <summary>
		/// Creates a markup from a string.
		/// </summary>
		/// <param name="elementFactory">A <see cref="XamlElementFactory"/> used to create the resulting markup.</param>
		/// <param name="markupText">A markup extension as a string, starting with a '{'. Eg <c>{x:Static}</c></param>
		/// <returns>A <see cref="IMarkup"/> representing <paramref name="markupText"/>.</returns>
		[NotNull]
		public static IMarkup CreateMarkup([NotNull] this XamlElementFactory elementFactory, [NotNull] string markupText) {
			if (elementFactory == null)
				throw new ArgumentNullException("elementFactory");
			if (markupText == null)
				throw new ArgumentNullException("markupText");

			var tokenTypes = (XamlTokenTypes) elementFactory.XmlTokenType;
			IXmlAttributeValue attrValue = elementFactory.CreateAttributeValue(tokenTypes.MARKUP_LBRACE, new StringBuffer(markupText), 0, markupText.Length);
			IPropertyAttributeValue propAttrValue = MarkupExtensionsTreeBuilder.ParseTypeNameOrMarkupAttributeValue(attrValue);
			var markup = propAttrValue.FirstChild as IMarkup;
			Assertion.Assert(markup != null, "markup != null");
			return markup;
		}

		/// <summary>
		/// Creates a markup attribute from a string.
		/// </summary>
		/// <param name="elementFactory">A <see cref="XamlElementFactory"/> used to create the resulting markup attribute.</param>
		/// <param name="markupAttributeText">A markup attribute as a string.</param>
		/// <returns>A <see cref="IMarkupAttribute"/> representing <paramref name="markupAttributeText"/>.</returns>
		[NotNull]
		public static IMarkupAttribute CreateMarkupAttribute([NotNull] this XamlElementFactory elementFactory, [NotNull] string markupAttributeText) {
			if (elementFactory == null)
				throw new ArgumentNullException("elementFactory");
			if (markupAttributeText == null)
				throw new ArgumentNullException("markupAttributeText");

			return elementFactory.CreateMarkup("{Markup " + markupAttributeText + "}").GetAttributes().First();
		}

	}

}